package com.guangfeng.yql.comm.util;


import cn.hutool.core.lang.Assert;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.HashMap;
import java.util.Map;

public class TokenUtils {
    /**
     * 该方法使用HS256算法和Secret:bankgl生成signKey
     */
    private static Key getKeyInstance() {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("0e2C9b8Y2ae842fbAW19d25fGa06b51B");
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        return signingKey;
    }

    /**
     * 使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
     */
    public static String creatJWT(Map<String, Object> claims) {
        JwtBuilder builder = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS256, getKeyInstance());
        return builder.compact();
    }

    /**
     * 创建token
     */
    public static String setToken(Integer id) {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("createMillis", System.currentTimeMillis());
        dataMap.put("id", id);
        return TokenUtils.creatJWT(dataMap);
    }

    public static String createToken(String param) {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("createMillis", System.currentTimeMillis());
        dataMap.put("param", param);
        return TokenUtils.creatJWT(dataMap);
    }


    /**
     * 解密token获取登录id
     */
    public static Integer getToken(String token) {
        Map<String, Object> jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(token).getBody();
        Assert.notNull(jwtClaims.get("id"), "无效token，请重新登录");
        return Integer.parseInt(jwtClaims.get("id").toString());
    }


    /**
     * 解析Token，同时也能验证Token，当验证失败返回null
     *
     * @param jwt
     */
    public static String parseJWT(String jwt) {
        if (jwt.split("\\.").length == 3) {
            //获取sign
            String sign = jwt.split("\\.")[2];
            try {
                Map<String, Object> jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
                return jwtClaims.get("param").toString();
            } catch (Exception e) {
                e.printStackTrace();
                Assert.isTrue(false, "无效token，请重新登录");
            }
        } else {
            Assert.isTrue(false, "无效token，请重新登录");
        }
        return null;
    }

    /**
     * 获取Token中的参数：短信验证码
     *
     * @param jwt
     */
    public static String getTokenBySms(String jwt) {
        Map<String, Object> resultMap = new HashMap<>();
        if (jwt.split("\\.").length == 3) {
            String sign = jwt.split("\\.")[2];
            Map<String, Object> jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
            Long createMillis = (Long) jwtClaims.get("createMillis") + Integer.parseInt("300000");//计算token失效时间
            long nowMillis = System.currentTimeMillis();//当前时间
            if (nowMillis >= createMillis) {
                Assert.isTrue(false, "验证码已过期");
            }
            return jwtClaims.get("param").toString();
        } else {
            Assert.isTrue(false, "验证码参数异常");
        }
        return null;
    }

}